package com.example.srm.project.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.srm.auth.anno.Authority;
import com.example.srm.common.controller.BaseController;
import com.example.srm.constant.ProjectApplicationConstant;
import com.example.srm.constant.ProjectStatusConstant;
import com.example.srm.domain.TProject;
import com.example.srm.domain.TProjectApplication;
import com.example.srm.domain.TUser;
import com.example.srm.domain.vo.Result;
import com.example.srm.project.service.TProjectApplicationService;
import com.example.srm.project.service.TProjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author: admin
 * @time: 2021/11/30 17:12
 * @describe: 项目申报操作
 */
@RestController
@RequestMapping("/project_application")
@Slf4j
@Transactional
@CrossOrigin
public class TProjectApplicationController extends BaseController<TProjectApplicationService, TProjectApplication> {
    @Autowired
    private TProjectService tProjectService;

    /**
     * 进行申报
     * @param tProjectApplication 申报的内容
     * @param request
     * @return 是否申请成功
     * @throws Exception
     */
    @Override
    @Authority(auth = "account:project:application")
    public Result save(@RequestBody TProjectApplication tProjectApplication, HttpServletRequest request) throws Exception {
        try {
            //根据项目id查询项目具体信息
            TProject tProject = tProjectService.getById(tProjectApplication.getProjectId());
            //得到 草稿 的状态码
            int notDeclaredCode = ProjectStatusConstant.NOT_DECLARED.getCode();
            //得到 申报失败 的状态码
            int failProjectAuditCode = ProjectStatusConstant.FAIL_PROJECT_AUDIT.getCode();
            //得到 待申报(申请变更成功)等同草稿 的状态码
            int successUpdateAuditCode = ProjectStatusConstant.SUCCESS_UPDATE_AUDIT.getCode();
            //得到项目当前的状态
            Integer tProjectStatus = tProject.getStatus1();

            //判断项目当前的状态是否可以进行申报
            if (tProjectStatus!=notDeclaredCode && tProjectStatus!=failProjectAuditCode && tProjectStatus!=successUpdateAuditCode){
                return new Result().setMsg("当前项目状态不能进行该操作");
            }

            //根据项目id 查询项目是否申报过
            TProjectApplication tProjectApplicationByProjectId = baseIService.getOne(new QueryWrapper<TProjectApplication>().eq("project_id", tProjectApplication.getProjectId()));
            //得到项目当前申报状态的name
            String projectApplicationStatusName = ProjectApplicationConstant.ON_APPLIACTION.getName();
            //用于保存修改或保存项目申报信息是否成功
            boolean flag =false;
            //如果项目未申报过
            if (tProjectApplicationByProjectId==null){
                //设置项目申报信息
                tProjectApplicationByProjectId = setProjectApplicationInfo(tProjectApplication, projectApplicationStatusName, request);
                //保存申报信息
                flag =  baseIService.save(tProjectApplicationByProjectId);
            }else {
                //设置申报信息的状态
                tProjectApplicationByProjectId.setStatus(projectApplicationStatusName);

                //修改申报状态
                flag = baseIService.updateById(tProjectApplicationByProjectId);
            }
            //修改项目当前状态
            UpdateWrapper<TProject> updateWrapper = new UpdateWrapper<TProject>()
                    .eq("id", tProjectApplicationByProjectId.getProjectId()) //设置根据id进行修改
                    .set("status", ProjectStatusConstant.PROJECT_AUDIT.getCode()); //设置修改的状态为申报中
            //进行修改
            boolean update = tProjectService.update(updateWrapper);
            return new Result().setSuccess(flag&&update);
        }catch (Exception e){
            log.error("保存失败",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result().setMsg("保存失败，请检查参数是否合法."+e.getMessage());
        }
    }

    /**
     * 项目申报驳回
     * @param tProjectApplication
     * @param request
     * @return
     * @throws Exception
     */
    @PutMapping("/not_pass")
    @Authority(auth = "account:application:notpass")
    public Result not_pass(@RequestBody TProjectApplication tProjectApplication, HttpServletRequest request) throws Exception {
        try {
            //得到项目当前申报状态的name【申请申报失败】
            String projectApplicationStatus = ProjectApplicationConstant.FAIL_APPLICATION.getName();
            //得到项目状态的code【项目申报失败】
            int projectStatusCode = ProjectStatusConstant.FAIL_PROJECT_AUDIT.getCode();
            boolean flag = updateProjectApplicationStatusAndProjectStatus(tProjectApplication, projectApplicationStatus, projectStatusCode, request);
            return new Result().setSuccess(flag);
        }catch (Exception e){
            log.error("申报失败",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result().setMsg("申报失败，请检查参数是否合法."+e.getMessage());
        }
    }

    /**
     * 项目申报通过
     * @param tProjectApplication
     * @param request
     * @return
     * @throws Exception
     */
    @PutMapping("/pass")
    @Authority(auth = "account:application:pass")
    public Result pass(@RequestBody TProjectApplication tProjectApplication, HttpServletRequest request) throws Exception {
        try {
            //得到项目当前申报状态的name【申请申报成功】
            String projectApplicationStatus = ProjectApplicationConstant.SUCCESS_APPLICATION.getName();
            //得到项目状态的code【项目未结题】
            int projectStatusCode = ProjectStatusConstant.NOT_CONCLUSION.getCode();

            boolean flag = updateProjectApplicationStatusAndProjectStatus(tProjectApplication, projectApplicationStatus, projectStatusCode, request);
            return new Result().setSuccess(flag);
        }catch (Exception e){
            log.error("申报失败",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result().setMsg("申报失败，请检查参数是否合法."+e.getMessage());
        }
    }




    /**
     * 修改项目状态以及项目申报状态
     * @param tProjectApplication 前端发送的申报数据
     * @param applicationStatusName 申报状态名
     * @param projectStatusCode 项目状态
     * @param request 请求信息
     * @return 是否成功
     */
    public boolean updateProjectApplicationStatusAndProjectStatus(TProjectApplication tProjectApplication,String applicationStatusName,int projectStatusCode, HttpServletRequest request){
        //设置项目实体类
//        TProjectApplication projectApplicationInfo = setProjectApplicationInfo(tProjectApplication, applicationStatusName, request);
        tProjectApplication.setStatus(applicationStatusName);
        //修改项目申报状态
//        boolean save = baseIService.updateById(projectApplicationInfo);
        System.out.println(tProjectApplication);
        boolean save = baseIService.updateById(tProjectApplication);
        //修改项目当前状态
        UpdateWrapper<TProject> updateWrapper = new UpdateWrapper<TProject>()
                .eq("id", tProjectApplication.getProjectId()) //设置根据id进行修改
                .set("status", projectStatusCode); //设置修改的状态为申报失败
        //进行修改项目状态
        boolean update = tProjectService.update(updateWrapper);
        return save&&update;
    }

    /**
     * 未申报时，设置项目申报实体类
     * @param tProjectApplication 前端发送的申报对象
     * @param applicationStatusName 项目申报的状态
     * @param request 请求信息
     * @return 项目申报实体类
     */
    public TProjectApplication setProjectApplicationInfo(TProjectApplication tProjectApplication, String applicationStatusName, HttpServletRequest request){
        //从session中取出用户信息
        TUser userinfo = (TUser) request.getSession().getAttribute("USERINFO");
        //赋值申报人
        tProjectApplication.setApplicant(userinfo.getUserName());
        //赋值申报时间
        tProjectApplication.setApplicateTime(new Date());
        //设置申报状态
        tProjectApplication.setStatus(applicationStatusName);
        return tProjectApplication;
    }

    @Override
    public void beforeSave(TProjectApplication tProjectApplication) throws Exception {

    }
}
